using Circus.Syntax.Lexer;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
namespace Circus.Syntax
{
	[DesignerCategory("Code"), ToolboxItem(true), ToolboxBitmap(typeof(Parser), "Images.Parser.bmp")]
	[Serializable]
	public class Parser : Circus.Syntax.Lexer.Lexer
	{
		protected internal class ParserState
		{
			public int LineIndex;
			public int Token;
			public int TokenPos;
			public int CurrentPos;
			public int State;
			public int PrevToken;
		}
		private IList<Parser.ParserState> stack;
		private int state;
		private int token;
		protected int lineIndex;
		protected int tokenPos;
		protected int currentPos;
		protected int prevToken = -1;
		protected string source;
		private IStringList strings;
		private IStringList internalStrings;
		protected internal IList<Parser.ParserState> Stack
		{
			get
			{
				return this.stack;
			}
		}
		[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public virtual int Token
		{
			get
			{
				return this.token;
			}
			set
			{
				if (this.token != value)
				{
					this.token = value;
					this.OnTokenChanged();
				}
			}
		}
		[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public virtual int State
		{
			get
			{
				return this.state;
			}
			set
			{
				if (this.state != value)
				{
					this.state = value;
					this.StateChanged();
				}
			}
		}
		[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public virtual string TokenString
		{
			get
			{
				return (this.source != null && this.tokenPos < this.source.Length) ? this.source.Substring(this.tokenPos, Math.Min(this.currentPos, this.source.Length) - this.tokenPos) : string.Empty;
			}
		}
		[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public virtual Point TokenPosition
		{
			get
			{
				return this.ValidatePosition(new Point(this.tokenPos, this.lineIndex));
			}
		}
		[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public virtual Point CurrentPosition
		{
			get
			{
				return this.ValidatePosition(new Point(this.currentPos, this.lineIndex));
			}
		}
		[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public virtual bool Eof
		{
			get
			{
				return this.token == -1 || this.strings == null || this.lineIndex >= this.strings.Count;
			}
		}
		[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public virtual IStringList Strings
		{
			get
			{
				return this.strings;
			}
			set
			{
				if (this.strings != value)
				{
					this.strings = value;
					this.OnStringsChanged();
				}
			}
		}
		[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public virtual string[] Lines
		{
			get
			{
				string[] result;
				if (this.strings == null)
				{
					result = null;
				}
				else
				{
					string[] array = new string[this.strings.Count];
					this.strings.CopyTo(array, 0);
					result = array;
				}
				return result;
			}
			set
			{
				if (this.internalStrings == null)
				{
					this.internalStrings = new StringList();
				}
				else
				{
					this.internalStrings.Clear();
				}
				this.strings = this.internalStrings;
				for (int i = 0; i < value.Length; i++)
				{
					string item = value[i];
					this.strings.Add(item);
				}
				this.OnStringsChanged();
			}
		}
		public Parser()
		{
			this.stack = new List<Parser.ParserState>();
		}
		protected bool IsStackEmpty()
		{
			return this.stack.Count == 0;
		}
		protected virtual void ResetLine(int line)
		{
			this.source = ((this.strings != null && line >= 0 && line < this.strings.Count) ? this.strings[line] : null);
		}
		protected virtual bool UpdateLine()
		{
			this.currentPos = 0;
			this.tokenPos = 0;
			this.source = null;
			while (this.strings != null && (this.source == null || this.source == string.Empty) && this.lineIndex < this.strings.Count)
			{
				this.lineIndex++;
				this.ResetLine(this.lineIndex);
			}
			return this.source != null && this.source != string.Empty;
		}
		protected virtual bool IsValidToken(int tok)
		{
			return true;
		}
		protected virtual Point ValidatePosition(Point position)
		{
			return (this.strings == null || position.Y < this.strings.Count) ? position : ((this.strings.Count == 0) ? new Point(0, 0) : new Point(this.strings[this.strings.Count - 1].Length, this.strings.Count - 1));
		}
		protected virtual int DoNextValidToken()
		{
			int num = this.NextToken();
			while (!this.Eof && !this.IsValidToken(num))
			{
				num = this.NextToken();
			}
			return num;
		}
		protected void SetToken(int token)
		{
			this.token = token;
		}
		protected virtual void StateChanged()
		{
		}
		protected virtual void OnStringsChanged()
		{
		}
		protected virtual void OnTokenChanged()
		{
		}
		public virtual void Reset()
		{
			this.Reset(0, 0, this.DefaultState);
		}
		public virtual void Reset(int line, int pos, int state)
		{
			this.lineIndex = line;
			this.token = 0;
			this.tokenPos = pos;
			this.prevToken = -1;
			this.currentPos = pos;
			this.State = state;
			this.ResetLine(line);
		}
		public virtual int NextToken()
		{
			this.tokenPos = this.currentPos;
			if (this.IsValidToken(this.token))
			{
				this.prevToken = this.token;
			}
			if ((this.source == null || this.currentPos >= this.source.Length) && !this.UpdateLine())
			{
				this.token = -1;
			}
			else
			{
				int num = 0;
				this.State = this.ParseText(this.state, this.lineIndex, this.source, ref this.tokenPos, ref num, ref this.token);
				this.currentPos = this.tokenPos + num;
			}
			return this.token;
		}
		public virtual int NextToken(out string str)
		{
			int result = this.NextToken();
			str = this.TokenString;
			return result;
		}
		public virtual int PeekToken()
		{
			this.SaveState();
			int result;
			try
			{
				result = this.NextToken();
			}
			finally
			{
				this.RestoreState();
			}
			return result;
		}
		public virtual int PeekToken(out string str)
		{
			this.SaveState();
			int result;
			try
			{
				result = this.NextToken();
				str = this.TokenString;
			}
			finally
			{
				this.RestoreState();
			}
			return result;
		}
		public virtual int PeekValidToken()
		{
			this.SaveState();
			int result;
			try
			{
				result = this.NextValidToken();
			}
			finally
			{
				this.RestoreState();
			}
			return result;
		}
		public virtual int PeekValidToken(out string str)
		{
			this.SaveState();
			int result;
			try
			{
				int num = this.NextValidToken();
				str = this.TokenString;
				result = num;
			}
			finally
			{
				this.RestoreState();
			}
			return result;
		}
		public virtual int NextValidToken()
		{
			int num = this.currentPos;
			int num2 = this.lineIndex;
			int num3 = this.token;
			return this.DoNextValidToken();
		}
		public virtual int NextValidToken(out string str)
		{
			int result = this.NextValidToken();
			str = this.TokenString;
			return result;
		}
		protected virtual Parser.ParserState CreateParserState()
		{
			return new Parser.ParserState();
		}
		protected virtual void SaveState(Parser.ParserState pstate)
		{
			pstate.LineIndex = this.lineIndex;
			pstate.Token = this.token;
			pstate.TokenPos = this.tokenPos;
			pstate.CurrentPos = this.currentPos;
			pstate.State = this.state;
			pstate.PrevToken = this.prevToken;
		}
		protected virtual void RestoreState(Parser.ParserState pstate)
		{
			this.lineIndex = pstate.LineIndex;
			this.token = pstate.Token;
			this.tokenPos = pstate.TokenPos;
			this.currentPos = pstate.CurrentPos;
			this.State = pstate.State;
			this.prevToken = pstate.PrevToken;
			this.ResetLine(this.lineIndex);
		}
		public virtual void SaveState()
		{
			Parser.ParserState parserState = this.CreateParserState();
			this.SaveState(parserState);
			this.stack.Add(parserState);
		}
		public virtual void RestoreState()
		{
			this.RestoreState(true);
		}
		public virtual void RestoreState(bool restore)
		{
			if (this.stack.Count > 0)
			{
				if (restore)
				{
					Parser.ParserState pstate = this.stack[this.stack.Count - 1];
					this.RestoreState(pstate);
				}
				this.stack.RemoveAt(this.stack.Count - 1);
			}
		}
	}
}
